/**
 * 
 */
package genericos.dao.hibernate.impl;

import genericos.dao.exeptions.PersistenceServiceException;
import genericos.dao.hibernate.UniversalHibernateDAO;

import java.io.Serializable;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * @author PUSDERKIS
 * 
 */
public class UniversalHibernateDAOImpl extends HibernateDaoSupport implements
		UniversalHibernateDAO {

	/**
	 * Used by the base DAO classes but here for your modification Get object
	 * matching the given key and return it.
	 */
	public Object get(Class refClass, Serializable key)
			throws PersistenceServiceException {
		Session s = null;

		try {
			s = getSession();

			return get(refClass, key, s);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"No se puede recuperar el objeto con id: " + key);
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"No se puede recuperar el objeto con id: " + key);
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Used by the base DAO classes but here for your modification Get object
	 * matching the given key and return it.
	 */
	protected Object get(Class refClass, Serializable key, Session s)
			throws PersistenceServiceException {
		try {
			return s.get(refClass, key);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"No se puede recuperar el objeto con id: " + key);
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"No se puede recuperar el objeto con id: " + key);
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Used by the base DAO classes but here for your modification Load object
	 * matching the given key and return it.
	 */
	public Object load(Class refClass, Serializable key)
			throws PersistenceServiceException {
		Session s = null;

		try {
			s = getSession();

			return load(refClass, key, s);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error("No se puede recuperar el objeto con id: "+key);
	         throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error("No se puede recuperar el objeto con id: "+key);
	         throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Used by the base DAO classes but here for your modification Load object
	 * matching the given key and return it.
	 */
	protected Object load(Class refClass, Serializable key, Session s)
			throws PersistenceServiceException {
		try {
			return s.load(refClass, key);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error("No se puede recuperar el objeto con id: "+key);
	         throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error("No se puede recuperar el objeto con id: "+key);
	         throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Return all objects related to the implementation of this DAO with no
	 * filter.
	 */
	public java.util.List findAll(Class clazz)
			throws PersistenceServiceException {
		Session s = null;

		try {
			s = getSession();

			return findAll(clazz, s);
		} catch (HibernateException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Return all objects related to the implementation of this DAO with no
	 * filter. Use the session given.
	 * 
	 * @param s
	 *            the Session
	 */
	protected java.util.List findAll(Class clazz, Session s)
			throws PersistenceServiceException {
		return findAll(clazz, s, getDefaultOrder());
	}

	/**
	 * @return el orden por defecto.
	 */
	private Order getDefaultOrder() {

		return null;
	}

	/**
	 * Return all objects related to the implementation of this DAO with no
	 * filter.
	 */
	public java.util.List findAll(Class clazz, Order defaultOrder)
			throws PersistenceServiceException {
		Session s = null;

		try {
			s = getSession();

			return findAll(clazz, s, defaultOrder);
		} catch (HibernateException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Return all objects related to the implementation of this DAO with no
	 * filter. Use the session given.
	 * 
	 * @param s
	 *            the Session
	 */
	protected java.util.List findAll(Class clazz, Session s, Order defaultOrder)
			throws PersistenceServiceException {
		try {
			Criteria crit = s.createCriteria(clazz);

			if (null != defaultOrder) {
				crit.addOrder(defaultOrder);
			}

			return crit.list();
		} catch (HibernateException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			logger.error("No se pueden recuperar los objetos del tipo: "
					+ this.getClass());
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Used by client DAO classes. This call forces a syncronization process
	 * between <br>
	 * session state and the database (NO COMMIT!). See Hibernate Documentation
	 * for a more <br>
	 * detailed description about flushing process and when to call it.
	 * 
	 * @throws PersistenceServiceException
	 */
	public void flush() throws PersistenceServiceException {
		try {
			getSession().flush();
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"flush\" de la sesión");
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"flush\" de la sesión");
			throw new PersistenceServiceException(ex);
		}
	}

	/**
	 * Returns the hibernate session
	 */
	public Session getHibernateSession() {
		try {
			return this.getSession();
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error("No se puede recuperar la sesion.");
	         throw new PersistenceServiceException(ex);
		}
	}

	/** 
	 * @see genericos.dao.hibernate.UniversalHibernateDAO#save(java.lang.Object)
	 */
	public void save(Object obj) throws PersistenceServiceException {
		try {
			getSession().save(obj);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"save\" del objeto.");
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"save\" del objeto.");
			throw new PersistenceServiceException(ex);
		}
	}

	/** 
	 * @see genericos.dao.hibernate.UniversalHibernateDAO#saveOrUpdate(java.lang.Object)
	 */
	public void saveOrUpdate(Object obj) throws PersistenceServiceException {
		
		try {
			getSession().saveOrUpdate(obj);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"save\" del objeto.");
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"save\" del objeto.");
			throw new PersistenceServiceException(ex);
		}
		
	}

	public void delete(Object obj) throws PersistenceServiceException {
		try {
			getSession().delete(obj);
		} catch (HibernateException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"delete\" del objeto.");
			throw new PersistenceServiceException(ex);
		} catch (DataAccessException ex) {
			Logger.getLogger(this.getClass()).error(
					"Error al hacer un \"delete\" del objeto.");
			throw new PersistenceServiceException(ex);
		}
		
	}

}
